<template>
  <el-form ref="formRef" :model="formData" label-width="80">
    <div class="flex-items group-name">
      <el-form-item
        label="分组名称"
        class="group-name_input"
        prop="customerGroupName"
        :rules="[{ required: true, message: '请输入分组名称', trigger: 'blur' }]"
      >
        <el-input placeholder="请输入" :maxlength="20" v-model="formData.customerGroupName" show-word-limit clearable />
      </el-form-item>
      <el-form-item label="排序">
        <el-input class="group-name_sort" type="number" v-model="formData.orderNum" :min="0" @input="inputSort" />
      </el-form-item>
    </div>
    <div class="group-name_tip">请输入分组名称，该名称会在“我的客户”筛选项出现</div>
    <el-form-item label="备注">
      <el-input type="textarea" placeholder="请输入" v-model="formData.desc" :autosize="{ minRows: 3 }" />
    </el-form-item>
    <el-form-item label="筛选条件">
      <el-button type="primary" link :icon="Plus" @click="handelAddGroup">条件组</el-button>
    </el-form-item>

    <div class="group-container" v-for="(item, conditionsIndex) in formData.conditions">
      <div class="group-not-type" v-if="conditionsIndex === 0">当</div>
      <el-select v-else class="group-type" placeholder="" v-model="item.groupType">
        <el-option label="且" value="AND"></el-option>
        <el-option label="或" value="OR"></el-option>
      </el-select>
      <div class="horizontal-line"></div>
      <div class="branch-line" :style="{ height: `${item.conditions.length * 43}px` }"></div>
      <div>
        <div class="conditions-list" v-for="(subItem, subIndex) in item.conditions" :key="subItem.fieldId">
          <!-- 所有表单字段 start -->
          <el-select
            class="form-field"
            :class="{ 'form-field-err': subItem.isErr }"
            placeholder="请选择"
            filterable
            v-model="subItem.fieldId"
            @change="changeField($event, subItem)"
          >
            <el-option
              v-for="fieldItem in conditionFields"
              :key="fieldItem.fieldId"
              :label="fieldItem.title"
              :value="fieldItem.fieldId"
            ></el-option>
          </el-select>
          <!-- 所有表单字段 end -->
          <!--条件关系 start -->
          <el-select class="condition-filter" placeholder="请先选择字段" v-model="subItem.compare">
            <el-option
              v-for="(typeItem, index) in conditionTypes[subItem.fieldName]"
              :key="`${typeItem.value}${index}`"
              :label="typeItem.label"
              :value="typeItem.value"
            ></el-option>
          </el-select>
          <!--条件关系  end -->
          <!--
        条件组件 start
         TODO: 根据字段类型动态渲染组件
           -->
          <div :class="{ 'form-field-err': subItem.isErr }">
            <!--    number   -->
            <template v-if="subItem.fieldName === 'NumberInput'">
              <el-input
                v-if="inputCompare.includes(subItem.compare)"
                style="width: 225px"
                type="number"
                v-model.number="subItem.value[0]"
                placeholder="请输入"
                clearable
              />
              <template v-if="rangeCompare.includes(subItem.compare)">
                <el-input type="number" style="width: 200px" v-model.number="subItem.value[0]" placeholder="请输入" clearable />
                <el-input type="number" style="width: 200px" v-model.number="subItem.value[1]" placeholder="请输入" clearable />
              </template>
            </template>

            <!--     string   -->
            <template v-if="subItem.fieldName === 'TextInput'">
              <el-input
                style="width: 225px"
                v-if="textCompare.includes(subItem.compare)"
                v-model="subItem.value[0]"
                placeholder="请输入"
                clearable
              />
              <el-select
                style="width: 225px"
                v-if="textCompareRange.includes(subItem.compare)"
                multiple
                filterable
                allow-create
                default-first-option
                collapse-tags-tooltip
                :reserve-keyword="false"
                collapse-tags
                :max-collapse-tags="1"
                v-model="subItem.value"
              >
                <el-option v-for="textItem in subItem.value" :label="textItem" :value="textItem"></el-option>
              </el-select>
            </template>

            <!--     date   -->
            <template v-if="subItem.fieldName === 'DateTime'">
              <el-date-picker
                style="width: 225px"
                v-if="inputCompare.includes(subItem.compare)"
                v-model="subItem.value[0]"
                type="datetime"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                date-format="YYYY-MM-DD"
                time-format="HH:mm:ss"
              />
              <el-date-picker
                v-if="rangeCompare.includes(subItem.compare)"
                v-model="subItem.value"
                type="datetimerange"
                :shortcuts="pickerTimeShortcuts"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                date-format="YYYY-MM-DD"
                time-format="HH:mm:ss"
                range-separator="To"
                start-placeholder="Start date"
                end-placeholder="End date"
              />
            </template>

            <!--     select   -->
            <template v-if="subItem.fieldName === 'SelectInput'">
              <el-select style="width: 225px" v-model="subItem.value">
                <el-option v-for="selectItem in subItem.options" :label="selectItem.label" :value="selectItem.value"></el-option>
              </el-select>
            </template>

            <!--     MultipleSelect   -->
            <template v-if="subItem.fieldName === 'MultipleSelect'">
              <el-select
                style="width: 225px"
                multiple
                v-model="subItem.value"
                allow-create
                default-first-option
                collapse-tags-tooltip
                :reserve-keyword="false"
                collapse-tags
                :max-collapse-tags="1"
              >
                <el-option v-for="selectItem in subItem.options" :label="selectItem.label" :value="selectItem.value"></el-option>
              </el-select>
            </template>

            <!--    CascaderInput    -->
            <template v-if="subItem.fieldName === 'CascaderInput'">
              <el-cascader style="width: 225px" v-model="subItem.value" clearable :options="cascaderOptions"></el-cascader>
            </template>
          </div>
          <!--     条件组件 end   -->
          <el-button :icon="Delete" color="#fff" @click="handelDelCondition(item, subIndex, conditionsIndex)"></el-button>
        </div>
        <el-button type="info" color="#F2F3F5" :icon="Plus" @click="handelAddCondition(item)"></el-button>
      </div>
    </div>
  </el-form>
</template>

<script setup>
/**
 * TODO:穷举,未封装
 */
import { computed, getCurrentInstance, ref } from "vue";
import { Delete, Plus } from "@element-plus/icons-vue";
import cascaderOptions from "@/assets/pca-code";
import { pickerTimeShortcuts } from "../utils";
import { fieldList } from "@/apis/clientGroup/clientGroup";
import { selectDictDataByType, dictList } from "@/apis/dict/dict";
import { conditionTypes, inputCompare, rangeCompare, textCompare, textCompareRange } from "@/views/clientGroup/data";
import { nonDictData } from "@/apis/clientManager";

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  }
});
const emit = defineEmits(["update:modalValue"]);
const { proxy } = getCurrentInstance();

const formData = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emit("update:modalValue", val);
  }
});

const inputSort = data => {
  formData.value.orderNum = data < 0 ? "" : data;
};

const getSelectOptions = (subItem, props) => {
  const { sourceType, sourceValue } = props && JSON.parse(props);
  switch (sourceType) {
    case "dbo:dict":
      selectDictDataByType(sourceValue).then(res => {
        const { data } = res;
        const dictData = data || [];
        subItem.options = dictData.map(item => ({
          label: item.dictLabel,
          value: item.dictCode
        }));
      });
      break;
    case "sass:dict":
      dictList({ dictType: sourceValue }).then(res => {
        const { data } = res;
        const dictData = data || [];
        subItem.options = dictData.map(item => ({
          label: item.dictLabel,
          value: item.dictCode
        }));
      });
      break;
    case "formTable":
      subItem.options = props?.option || [];
      break;
    case "remote":
      nonDictData({ method: sourceValue }).then(res => {
        const { data } = res;
        subItem.options = data || [];
      });
      break;
    default:
      subItem.options = [];
  }
};
const changeField = (e, subItem) => {
  subItem.compare = "EQ";
  const fieldData = conditionFields.value.find(item => item.fieldId === e);
  if (fieldData) {
    subItem.fieldName = fieldData.fieldName;
    subItem.physicsName = fieldData.physicsName;
    if (["SelectInput", "MultipleSelect"].includes(fieldData.fieldName)) {
      subItem.compare = "IN";
      getSelectOptions(subItem, fieldData?.props || {});
    }
  }
};

const handelAddGroup = () => {
  formData.value.conditions.push({
    groupType: "AND",
    conditions: [
      {
        fieldName: "",
        fieldId: "",
        compare: "",
        value: []
      }
    ]
  });
};
const handelAddCondition = item => {
  item.conditions.push({
    fieldName: "",
    fieldId: "",
    compare: "",
    value: []
  });
};
const handelDelCondition = (item, index, conditionsIndex) => {
  item.conditions.splice(index, 1);
  if (!item.conditions?.length) {
    formData.value.conditions.splice(conditionsIndex, 1);
  }
};

const conditionFields = ref([]);
const getFieldList = async () => {
  try {
    const { data } = await fieldList();
    conditionFields.value = data || [];
  } catch (err) {
    console.log(err);
  }
};

const submit = () => {
  return new Promise((resolve, reject) => {
    try {
      proxy.$refs.formRef.validate(val => {
        let result = val;
        if (val) {
          result = true;
          formData.value.conditions.forEach(item => {
            if (item.conditions?.length) {
              item.conditions.forEach(subItem => {
                subItem.isErr = false;
                if (!subItem.fieldName || !subItem.fieldId || !subItem.compare || !subItem.value.length) {
                  result = false;
                  subItem.isErr = true;
                }
              });
            }
          });
        }
        resolve(result);
      });
    } catch (err) {
      reject(err);
    }
  });
};

defineExpose({
  submit
});

getFieldList();
</script>

<style scoped lang="scss">
@use "@/assets/styles/mixin";

// TODO:  通用样式
:deep(.el-input__wrapper),
:deep(.el-select__wrapper),
:deep(.el-textarea__inner),
:deep(.el-input__count),
:deep(.el-input__count-inner) {
  background-color: #f2f3f5 !important;
}

.group-name {
  :deep(.el-form-item) {
    margin-bottom: 0 !important;
  }
  &_input {
    :deep(.el-input) {
      width: 700px;
    }
  }
  &_tip {
    margin-bottom: 20px;
    padding-left: 79px;
    font-weight: 400;
    font-size: 10px;
    color: #86909c;
    line-height: 22px;
  }
}

.group-container {
  @include mixin.flex-align;
  .horizontal-line {
    width: 16px;
    height: 1px;
    background-color: #e5e6eb;
  }
  .branch-line {
    width: 16px;
    height: 42px;
    border: 1px solid #e5e6eb;
    border-right: 0;
  }
  & + .group-container {
    margin-top: 30px;
  }
}

.group-not-type {
  @include mixin.flex-inline-flex;
  width: 60px;
  height: 32px;
  background-color: #f2f3f5;
  border-radius: 4px;
  box-shadow: 0 0 0 1px #dcdfe6 inset;
}
.group-type {
  width: 60px;
  :deep(.el-select__wrapper) {
    width: 60px;
  }
}

.conditions-list {
  @include mixin.flex-align;
  flex-wrap: nowrap;
  gap: 10px;
  margin-bottom: 10px;
  .form-field {
    width: 200px;
  }
  .form-field-err {
    border: 1px solid var(--el-color-danger);
    border-radius: 4px;
  }
  .condition-filter {
    width: 150px;
  }
}
</style>
